#pragma once

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "Public.h"

using namespace std;

class Address {
public:
	Address();
	Address(const string & ip, const int port);
	Address(const Address & other);
	Address & operator =(const Address & other);
	~Address();
	
	int getPort();
	string getIP();

	void setSocket(int fd){_fd = fd;}
	int getSocket(){return _fd;}

	int setAddress(const string & ip, const int port);
	int length() {return sizeof(_addr);}

	struct sockaddr_in &getAddr() {return _addr;}
private:
	struct sockaddr_in _addr;
	int _fd;
};

class Socket{
public:
//static mothed
	static int Poll(int fd, short events, int timeout);
	static int Read(int fd, void *buf, size_t len, int timeout);
	static int Write(int fd, void *buf, size_t len, int timeout);

	static int tcpRead(int fd, void *buf, int len, int timeout);
	static int tcpWrite(int fd, void *buf, int len, int timeout);
	static int tcpConnect(Address &peerAddr);
	//static int tcpAccept(int fd, struct sockaddr *addr, socklen_t * len);
	static int tcpAccept(int fd, vector<int> &fdVec, vector<Address> &addrVec);
	static int tcpClose(int fd);
	static int tcpAlive(int fd);

	static int tcpEpollWait(int fd, struct epoll_event *events, int maxevent, int timeout);
	static int tcpEpollAdd(int epfd, int fd, struct epoll_event *ev);
	static int setNonBlock(int fd);

//	static int tcpEpollCtl(int epfd, int fd, void *ptr, int events);
//end
/*
	Socket():_socketFd(-1), _status(NOTUSE){}
	Socket(int fd, Address addr):_socketFd(fd), _peerAddr(addr), _status(NOTUSE){}
	~Socket();
	int read(void *buf, int len, int timeout);
	int write(void *buf, int len, int timeout);
	int connect();
//	int accept(int listenFd, std::vector<Address>);
	bool alive();
	int close(int fd);

	void reset();

	struct timeval getAcceptTime(){return _acceptTime;}
	struct timeval getConnectTime(){return _connectTime;}
	struct timeval getLastActiveTime(){return _lastActiveTime;}
	Address &getPeerAddr(){return _peerAddr;}
	Address &getAddr(){return _addr;}
	int getSocketFd(){return _socketFd;}
	SocketStatus getSocketStatus(){return _status;}

	void setAcceptTime(struct timeval t){_acceptTime = t;}
	void setConnectTime(struct timeval t){_connectTime = t;}
	void setLastActiveTime(struct timeval t){_lastActiveTime = t;}
	void setPeerAddr(Address addr){_peerAddr = addr;}
	void setSocketStatus(SocketStatus s){_status = s;}
private:
	struct timeval _acceptTime;
	struct timeval _connectTime;
	struct timeval _lastActiveTime;
	Address _peerAddr;
	Address _addr;
	void *_dataBuf;
	int _socketFd;
	SocketStatus _status;
*/
};


